package com.next

import grails.transaction.Transactional
import org.springframework.security.access.annotation.Secured

import static org.springframework.http.HttpStatus.*
import org.apache.poi.xssf.usermodel.XSSFWorkbook

@Secured(['ROLE_ADMINISTRATOR', 'ROLE_COMPANY_ADMINISTRATOR', 'ROLE_COMPANY_USER'])
@Transactional(readOnly = true)
class AccountController
{
    static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]

    def springSecurityService
    def exportService
    def subscribeService
    def excelImportService

    // @CompileStatic
    def index(Integer max)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def accountList
        def count
        def isAdmin = false
        if (UserRole.findByUserAndRole(User.findByUsername(username), Role.findByAuthority('ROLE_ADMINISTRATOR')) || UserRole.findByUserAndRole(User.findByUsername(username), Role.findByAuthority('ROLE_COMPANY_ADMINISTRATOR')))
        {
            isAdmin = true
            accountList = Account.findAll("from Account where active = true order by modifiedDate desc", [max: params.max ?: 10, offset: params.offset ?: 0])
            count = Account.executeQuery("select count(id) from Account where active = true")
        }
        else
        {
            accountList = Account.findAll("from Account where user.username = '${username}' and active = true order by modifiedDate desc", [max: params.max ?: 10, offset: params.offset ?: 0])
            count = Account.executeQuery("select count(id) from Account where user.username = '${username}' and active = true")
        }

        respond accountList, model: [accountCount: count[0], params: params, isAdmin: isAdmin]
    }

    // @CompileStatic
    def show(Account account)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)
        def addressList = Address.findAll("from Address where account.id = ?", [account.id])
        def noteList = Note.findAll("from Note where account.id = ?", [account.id])
        def attachmentList = Attachment.findAll("from Attachment where account.id = ?", [account.id])
        def appointmentList = Activity.findAll("from Activity where account.id = ? and type.id = ?", [account.id, ActivityType.find("from ActivityType where name = 'Appointment'")?.id])
        def taskList = Activity.findAll("from Activity where account.id = ? and type.id = ?", [account.id, ActivityType.find("from ActivityType where name = 'Task'")?.id])
        def teamList = AccountTeam.findAll("from AccountTeam where account.id = ?", [account.id])
        def flexFieldInstanceList = FlexFieldInstance.findAll("from FlexFieldInstance where account.id = ?", [account.id])
        def opportunityList = Opportunity.findAll("from Opportunity where account.id = ? order by modifiedDate desc", [account.id])
        def assetList = Asset.findAll("from Asset where account.id = ? order by createdDate desc", [account.id])
        def follow = Follow.findByAccountAndUser(account, user)

        // 模块权限控制
        def accountTeam = AccountTeam.find("from AccountTeam where account.id = ? and user.username = ?", [account.id, username])
        def teamRole = accountTeam?.teamRole
        def contactPermission = accountTeam?.contactPermission
        def activityPermission = accountTeam?.activityPermission
        def teamPermission = accountTeam?.teamPermission
        def attachmentPermission = accountTeam?.attachmentPermission
        def notePermission = accountTeam?.notePermission
        def flexFieldPermission = accountTeam?.flexFieldPermission
        def addressPermission = accountTeam?.addressPermission

        respond account, model: [addressList: addressList, noteList: noteList, attachmentList: attachmentList, appointmentList: appointmentList, taskList: taskList, teamList: teamList, flexFieldInstanceList: flexFieldInstanceList, teamName: 'accountTeam', teamRole: teamRole, contactPermission: contactPermission, activityPermission: activityPermission, teamPermission: teamPermission, attachmentPermission: attachmentPermission, notePermission: notePermission, flexFieldPermission: flexFieldPermission, addressPermission: addressPermission, opportunityList: opportunityList, assetList: assetList, follow: follow]
    }

    // @CompileStatic
    def create()
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)

        Company company = Company.findAll()[0]
        Boolean enableTerritory = company.enableAccountTerritory
        def targetUri = request.getHeader("referer")
        respond new Account(params), model: [enableTerritory: enableTerritory, user: user, targetUri: targetUri]
    }

    @Transactional
    def save(Account account)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)
        Company company = Company.findAll()[0]
        Boolean enableTerritory = company.enableAccountTerritory

        def existContact = []
        account?.contacts?.each { contact ->
            if (Contact.findByCellphone(contact?.cellphone))
            {
                existContact.add(contact)
            }
        }
        if (existContact)
        {
            flash.message = "联系人${existContact}已被登记"
            respond account, view: 'create', model: [enableTerritory: enableTerritory, user: user, targetUri: params['targetUri']]
            return
        }

        if (account == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }
        if (account.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond account.errors, model: [enableTerritory: enableTerritory, user: user, targetUri: params['targetUri']], view: 'create'
            return
        }
        if (enableTerritory && !account?.territory)
        {
            flash.message = "请选择销售区域"
            respond account, view: 'create', model: [enableTerritory: enableTerritory, user: user, targetUri: params['targetUri']]
        }
        else
        {
            account.save flush: true

            request.withFormat {
                form multipartForm {
                    flash.message = message(code: 'default.created.message', args: [message(code: 'account.label',
                                                                                            default: 'Account'), account
                        .id])
                    // redirect account
                    redirect uri: params['targetUri']
                }
                '*' { respond account, [status: CREATED] }
            }
        }
    }

    // @CompileStatic
    def edit(Account account)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)

        TeamRole editTeamRole = TeamRole.findByName('Edit')
        AccountTeam accountTeam = AccountTeam.findByAccountAndUser(account, user)

        if (account?.user?.id == user?.id || accountTeam?.teamRole?.id == editTeamRole?.id || UserRole.findByUserAndRole(user, Role.findByAuthority('ROLE_ADMINISTRATOR')) || UserRole.findByUserAndRole(user, Role.findByAuthority('ROLE_COMPANY_ADMINISTRATOR')))
        {
            respond account, model: [user: user]
        }
        else
        {
            flash.message = "没有编辑权限"
            redirect uri: request.getHeader("referer")
            // respond account, view: 'show'
        }
    }

    @Transactional
    def update(Account account)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)

        if (account == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (account.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond account.errors, model: [user: user], view: 'edit'
            return
        }

        account.save flush: true

        subscribeService.sendSubscribe account

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.updated.message', args: [message(code: 'account.label',
                                                                                        default: 'Account'), account
                    .id])
                redirect account
            }
            '*' { respond account, [status: OK] }
        }
    }

    @Transactional
    def delete(Account account)
    {

        if (account == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        account.delete flush: true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.deleted.message', args: [message(code: 'account.label',
                                                                                        default: 'Account'), account
                    .id])
                redirect action: "index", method: "GET"
            }
            '*' { render status: NO_CONTENT }
        }
    }

    protected void notFound()
    {
        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.not.found.message', args: [message(code: 'account.label',
                                                                                          default: 'Account'), params
                    .id])
                redirect action: "index", method: "GET"
            }
            '*' { render status: NOT_FOUND }
        }
    }

    // @CompileStatic
    def searchAccount()
    {
        def username = springSecurityService?.getPrincipal()?.username
        String name = params["name"]
        String type = params["type"]
        String level = params["level"]

        String sql = "from Account where active = true"
        if (!UserRole.findByUserAndRole(User.findByUsername(username), Role.findByAuthority('ROLE_ADMINISTRATOR')) && !UserRole.findByUserAndRole(User.findByUsername(username), Role.findByAuthority('ROLE_COMPANY_ADMINISTRATOR')))
        {
            sql += " and user.username='${username}'"
        }
        if (name)
        {
            sql += " and name like '%${name}%'"
        }
        if (type)
        {
            sql += " and type.name like '%${type}%'"
        }
        if (level)
        {
            sql += " and level.name like '%${level}%'"
        }
        String countSql = "select count(id) " + sql
        sql += " order by modifiedDate desc"

        def list = Account.findAll(sql, [max: params.max ?: 10, offset: params.offset ?: 0])
        def count = Account.executeQuery(countSql)

        respond list, model: [accountCount: count[0], params: params], view: 'index'
    }

    def exportAccount()
    {
        if (!params.max)
        {
            params.max = 10
        }
        def username = springSecurityService?.getPrincipal()?.username
        String name = params["name"]
        String type = params["type"]
        String level = params["level"]
        // String sql = "from Account where  user.username = '${username}'"
        String sql = "from Account where active = true"
        if (!UserRole.findByUserAndRole(User.findByUsername(username), Role.findByAuthority('ROLE_ADMINISTRATOR')) && !UserRole.findByUserAndRole(User.findByUsername(username), Role.findByAuthority('ROLE_COMPANY_ADMINISTRATOR')))
        {
            // sql += " and user.username='${username}'"
            flash.message = "没有操作权限"
            redirect action: "index", method: "GET"
            return
        }
        if (name)
        {
            sql += " and name like '%${name}%'"
        }
        if (type)
        {
            sql += " and type.name like '%${type}%'"
        }
        if (level)
        {
            sql += " and level.name like '%${level}%'"
        }
        String countSql = "select count(id) " + sql
        sql += " order by modifiedDate desc"
        def list = Account.findAll(sql)
        def count = Account.executeQuery(countSql)
        if (params?.f && params.f != "html")
        {
            response.contentType = grailsApplication.config.grails.mime.types[params.f]
            response.setHeader("Content-disposition", "attachment; filename=account.${params.extension}")
            List fields = ["name", "alias", "type.name", "level.name", "industry.name", "numberOfEmployees", "website", "registeredCapital", "parent.name", "territory.name", "user.fullName", "description", "active", "createdDate", "modifiedDate"]
            Map labels = ["name": "客户名称", "alias": "曾用名", "type.name": "类型", "level.name": "分级", "industry.name": "行业", "numberOfEmployees": "雇员数量", "website": "网站", "registeredCapital": "注册资本", "parent.name": "上级客户", "territory.name": "销售区域", "user.fullName": "所有者", "description": "描述", "active": "启用", "createdDate": "创建时间", "modifiedDate": "修改时间"]
            exportService.export(params.f, response.outputStream, list, fields, labels, [:], [:])
        }
    }

    @Transactional
    def importAccount()
    {
        // def file = request.getFile('myFile')
        def file = params.myFile
        if (file)
        {
            println "import account excel"
            def totalCount = 0
            def totalTypeCount = 0
            def insertCount = 0
            def insertFaiedCount = 0
            def existsCount = 0
            def insertList = []
            def insertFailedList = []
            def existsList = []

            def workbook = new XSSFWorkbook(file.getInputStream())
            Map CONFIG_ACCOUNT_COLUMN_MAP = [sheet: 'Sheet1',
                startRow: 1,
                columnMap: ['A': 'description',
                    'B': 'name',
                    'C': 'level',]]
            def accountMapList = excelImportService.columns(workbook, CONFIG_ACCOUNT_COLUMN_MAP)
            accountMapList?.each { Map mapParams ->
                totalTypeCount++
                def nameList = mapParams.name.split(params['splitName'])
                nameList.each { name ->
                    totalCount++
                    def accountParams = [:]
                    accountParams.description = mapParams.description
                    accountParams.name = name
                    accountParams.level = mapParams.level ? AccountLevel.findByName(mapParams.level) : null
                    accountParams['type'] = AccountType.findByName(params['type'])
                    accountParams['industry'] = Industry.findByName(params['industry'])
                    accountParams['user'] = User.findByUsername("xuweimeng")
                    def account = Account.findByName(name)
                    if (account)
                    {
                        existsCount++
                        existsList.add(name)
                    }
                    else
                    {
                        account = new Account(accountParams)
                        if (account.validate())
                        {
                            account.save flush: true
                            insertCount++
                            insertList.add(name)
                        }
                        else
                        {
                            println "insert ${name} failed:" + account.errors
                            insertFaiedCount++
                            insertFailedList.add(name)
                        }
                    }
                }
                println "mapParams:" + mapParams.description
            }
            println "totalTypeCount:" + totalTypeCount
            println "totalCount:" + totalCount
            println "existsCount:" + existsCount
            println "insertCount:" + insertCount
            println "insertFaiedCount:" + insertFaiedCount
            println "existsList:" + existsList
            println "insertList:" + insertList
            println "insertFailedList:" + insertFailedList
            flash.message = "import success!"
            return
        }
        println "prepare import account excel"
    }
}
